<template>
  <div class="app-param">
    <el-form ref="queryForm" :model="queryParams" :inline="true">
      <el-form-item label="分类名称" prop="name">
        <el-input v-model="queryParams.name" placeholder="请输入分类名称" clearable></el-input>
      </el-form-item>
      <el-form-item label="分类状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
          <el-option label="启用" value="0"></el-option>
          <el-option label="禁用" value="1"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item :inline="true">
        <el-button type="primary" icon="Search" @click="handleSearch">搜索</el-button>
        <el-button icon="Refresh" @click="handleReset">重置</el-button>
      </el-form-item>
    </el-form>

    <div>
      <el-button type="primary" plain size="small" icon="Plus" @click="handleAdd">新增</el-button>
      <el-button type="danger" plain size="small" icon="Delete" @click="handleDelete">删除</el-button>
      <el-button type="info" plain size="small" icon="Sort" @click="toggleExpandAll">展开/折叠</el-button>
    </div>

    <el-table
      :data="currentClassifyList"
      v-loading="loading"
      stripe
      ref="multipleTableRef"
      row-key="classifyId"
      :expand-row-keys="classifyIdsExpand"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="75" align="center" />
      <el-table-column prop="name" width="200" label="名称" align="left" />
      <el-table-column prop="sort" width="100" label="排序" align="center" />
      <el-table-column prop="status" label="状态" align="center">
        <template #default="scope">
          <el-switch
            v-model="scope.row.status"
            active-value="0"
            inactive-value="1"
            inline-prompt
            active-color="#13ce66"
            inactive-color="#ff4949"
            active-text="启"
            inactive-text="禁"
            @click="updateStatus(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="创建时间" align="center" />
      <el-table-column prop="updateTime" label="更新时间" align="center" />
      <el-table-column label="操作" align="center">
        <template #default="scope">
          <el-button size="small" type="text" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
          <el-button size="small" type="text" icon="Plus" @click="handleAdd(scope.row)">新增</el-button>
          <el-button size="small" type="text" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog v-model="visible" :title="title" width="500px" append-to-body destroy-on-close>
      <el-form :model="form" label-width="80px" :rules="rules" ref="formRef">
        <el-form-item label="上级分类" prop="pid">
          <el-cascader
            :options="options"
            v-model="form.pid"
            :props="props"
            placeholder="请选择"
            clearable
          />
        </el-form-item>
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入分类名称" />
        </el-form-item>
        <el-form-item label="分类排序" prop="sort">
          <el-input-number v-model="form.sort" :min="1" placeholder="请输入排序" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio v-model="form.status" label="0">正常</el-radio>
          <el-radio v-model="form.status" label="1">停用</el-radio>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" size="large" @click="submitForm(formRef)">确认</el-button>
          <el-button @click="visible = false" size="large">取消</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue'
import type { Classify } from '@/api/types/classify'
import { list, add, getClassifyTree, getClassify, update, deleteByIds } from '@/api/classify'
import type { ElForm, ElTable } from 'element-plus'
import { filterChild, deepCopy } from '@/utils/treeUtils'

type FormInstance = InstanceType<typeof ElForm>
const formRef = ref<FormInstance>()

const multipleTableRef = ref<InstanceType<typeof ElTable>>()

interface queryParamsType {
  name?: string,
  status?: string
}

const queryParams = reactive<queryParamsType>({
  name: undefined,
  status: undefined
})

const classifyList = ref<Classify[]>([])

const currentClassifyList = ref<(Classify | undefined)[]>([])

const multipleSelection = ref<Classify[]>([])

const loading = ref(false)

const visible = ref(false)

const title = ref('')

const classifyIdsExpand = ref()

const form = reactive<Classify>({
  classifyId: undefined,
  name: '',
  status: '',
  pid: 0,
  sort: 1
})

const rules = reactive({
  name: [
    {
      required: true,
      message: '请输入名称',
      trigger: 'blur'
    }
  ],
  status: [
    {
      required: true,
      message: '请选择状态',
      trigger: 'blur'
    }
  ],
  pid: [
    {
      required: true,
      message: '请选择父节点',
      trigger: 'blur'
    }
  ],
  sort: [
    {
      required: true,
      message: '请排序',
      trigger: 'blur'
    }
  ]
})

const options = ref<[]>()

/**
 * 表单加载选项
 */
const props = {
  checkStrictly: true,
  emitPath: false
}

onMounted(() => {
  loadList()
  loadClassifyTree()
})

/**
 * 加载表格数据
 */
const loadList = async () => {
  loading.value = true
  classifyList.value = await list()
  currentClassifyList.value = classifyList.value.map(node => deepCopy(node))
  loading.value = false
}

/**
 * 加载对话框树结构选择
 */
const loadClassifyTree = async () => {
  options.value = await getClassifyTree(0)
}

const handleSelectionChange = (val: Classify[]) => {
  multipleSelection.value = val
}

/**
 * 重置表单
 */
const reset = () => {
  form.name = ''
  form.status = ''
  form.pid = 0
  form.sort = 1
  form.classifyId = undefined
}

/**
 * 打开新增对话框
 * @param classify 
 */
const handleAdd = (classify: Classify | any) => {
  reset()
  if (classify) form.pid = classify.classifyId
  title.value = '新增'
  visible.value = true
}

/**
 * 打开修改对话框
 * @param classify 
 */
const handleUpdate = async (classify: Classify) => {
  reset()
  const one = await getClassify(classify.classifyId)
  form.classifyId = classify.classifyId
  form.pid = one.pid
  form.name = one.name
  form.sort = one.sort
  form.status = one.status
  title.value = '修改'
  visible.value = true
}

/**
 * 删除
 * @param classify 
 */
const handleDelete = async (classify: Classify | any) => {
  let isDelete;
  let ids = classify.classifyId || multipleSelection.value.map(classify => classify.classifyId).filter(id => id)
  let message = '是否要删除:' + getClassifyName(classify) + "节点"
  let children = checkChildren(multipleSelection.value)
  if (children.length > 0) {
    message = message + "<br/>" + String(children) + "存在子节点"
  }
  if (ids && ids.length !== 0) {
    try {
      await ElMessageBox.confirm(
        message,
        '提示',
        {
          dangerouslyUseHTMLString: true,
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )
      isDelete = await deleteByIds(ids)
      if (isDelete) {
        loadList()
        loadClassifyTree()
        ElMessage({
          message: '删除成功',
          type: 'success',
        })
      } else {
        ElMessage({
          message: '请选择删除数据',
          type: 'error',
        })
      }
    } catch (err) {

    }

  } else {
    ElMessage({
      message: '请选择删除数据',
      type: 'error',
    })
  }
}

/**
 * 检查是否有子节点
 * @param classifies 
 */
const checkChildren = (classifies: Classify[]) => {
  return classifies.map(node => {
    if (node.children && node.children.length > 0) {
      return node.name
    }
  }).filter(name => name)
}

/**
 * 获取分类名称
 * @param classify 
 */
const getClassifyName = (classify: Classify) => {
  return classify.name ? classify.name : String(multipleSelection.value.map(classify => classify.name).filter(name => name))
}

/**
 * 查询数据列表
 */
const handleSearch = () => {
  currentClassifyList.value = classifyList.value.map(node => deepCopy(node)).map(node => filterChild(queryParams.name, queryParams.status, node)).filter(node => node)
  currentClassifyList.value.map(node => expandRow(true, node))
}

/**
 * 展开行
 * @param expand 
 * @param classify 
 */
const expandRow = (expand: boolean, classify?: Classify) => {
  if (classify) {
    multipleTableRef.value!.toggleRowExpansion(classify, expand);
    classify.children?.map(node => expandRow(expand, node))
  }
}

/**
 * 重置查询条件
 */
const handleReset = () => {
  queryParams.name = undefined
  queryParams.status = undefined
  loadList()
  expandClassify.value = false
  currentClassifyList.value.map(node => expandRow(expandClassify.value, node))
}

/**
 * 更新状态
 * @param classify 
 */
const updateStatus = async (classify: Classify) => {
  console.log(classify)
  const isUpdate = await update(classify).finally(() => {
    loadList()
    loadClassifyTree()
  })
  if (isUpdate) {
    ElMessage({
      message: '修改成功',
      type: 'success',
    })
  }
}

/**
 * 提交表单
 */
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  const valid = await formEl.validate()
  if (!valid) return false
  let ok
  let message
  if (form.classifyId) {
    message = '修改成功'
    ok = await update(form)
  } else {
    message = '添加成功'
    ok = await add(form)
  }

  loadList()
  loadClassifyTree()
  visible.value = false
  if (ok) {
    ElMessage({
      message,
      type: 'success',
    })
  }
}

const expandClassify = ref<boolean>(false)

/**
 * 展开折叠
 */
const toggleExpandAll = () => {
  expandClassify.value = !expandClassify.value
  currentClassifyList.value.map(node => expandRow(expandClassify.value, node))
}

</script>